﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DevExpress.Xpo;
using DevExpress.Data.Filtering;
using WROA.Models.Entitys;
using WROA.Models.IServices;

namespace WROA.Models.Services
{
    public class MeetingService : Services, IMeetingService
    {

        /// <summary>
        /// 用户获取待审批的会议流程
        /// </summary>
        /// <param name="name"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public XPCollection GetAllApplyMeeting(string name, string position)
        {
            GroupOperator goProcedure1 = new GroupOperator();
            goProcedure1.Operands.Add(new BinaryOperator("Pr_type", "人员", BinaryOperatorType.Equal));
            goProcedure1.Operands.Add(new BinaryOperator("Pr_typevalue", name, BinaryOperatorType.Equal));
            GroupOperator goProcedure2 = new GroupOperator();
            goProcedure2.Operands.Add(new BinaryOperator("Pr_type", "职位", BinaryOperatorType.Equal));
            goProcedure2.Operands.Add(new BinaryOperator("Pr_typevalue", position, BinaryOperatorType.Equal));
            GroupOperator goProcedure = new GroupOperator(GroupOperatorType.Or, goProcedure1, goProcedure2);

            XPCollection xpProcedure = new XPCollection(typeof(Procedure), goProcedure);
            XPCollection xpApplyMeeting = null;
            foreach (Procedure p in xpProcedure)
            {
                GroupOperator go = new GroupOperator();
                go.Operands.Add(new BinaryOperator("Procedure", p, BinaryOperatorType.Equal));
                go.Operands.Add(new BinaryOperator("Am_state", "未结束", BinaryOperatorType.Equal));
                XPCollection xp = new XPCollection(typeof(ApplyDocument), go);
                xpApplyMeeting.AddRange(xp);
            }

            return xpApplyMeeting;
        }

        /// <summary>
        /// 根据id返回一个会议审批对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ApplyMeeting GetApplyMeeting(int id)
        {
            ApplyMeeting applyMeeting = null;
            XPCollection xp = new XPCollection(typeof(ApplyMeeting), new BinaryOperator("Oid", id, BinaryOperatorType.Equal));
            foreach (ApplyMeeting am in xp)
            {
                applyMeeting = am;
            }
            return applyMeeting;
        }

        /// <summary>
        /// 根据会议类型名称返回会议类型对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public MeetingType GetMeetingType(string name)
        {
            MeetingType meetingType = null;
            XPCollection xp = new XPCollection(typeof(MeetingType), new BinaryOperator("Mt_name", name, BinaryOperatorType.Equal));
            foreach (MeetingType mt in xp)
            {
                meetingType = mt;
            }
            return meetingType;
        }

        /// <summary>
        /// 根据流程和步骤获取步骤对象
        /// </summary>
        /// <param name="flow"></param>
        /// <param name="stepid"></param>
        /// <returns></returns>
        public Procedure GetProcedure(Flow flow, int stepid)
        {
            Procedure procedure = null;
            GroupOperator go = new GroupOperator();
            go.Operands.Add(new BinaryOperator("Flow", flow, BinaryOperatorType.Equal));
            go.Operands.Add(new BinaryOperator("step_id", stepid, BinaryOperatorType.Equal));
            XPCollection xp = new XPCollection(typeof(Procedure), go);
            foreach (Procedure p in xp)
            {
                procedure = p;
            }
            return procedure;
        }

        /// <summary>
        /// 根据id更新会议流程步骤
        /// </summary>
        /// <param name="id"></param>
        /// <param name="procedure"></param>
        public void UpdateApplyMeetingProcedure(int id, Procedure procedure)
        {
            XPCollection xp = new XPCollection(typeof(ApplyMeeting), new BinaryOperator("Oid", id, BinaryOperatorType.Equal));
            foreach (ApplyMeeting am in xp)
            {
                am.Procedure = procedure;
                am.Save();
            }
        }

        /// <summary>
        /// 根据id更新会议流程为已结束
        /// </summary>
        /// <param name="id"></param>
        public void UpdateApplyMeetingState(int id)
        {
            XPCollection xp = new XPCollection(typeof(ApplyMeeting), new BinaryOperator("Oid", id, BinaryOperatorType.Equal));
            foreach (ApplyMeeting am in xp)
            {
                am.Am_state = "已结束";
                am.Save();
            }
        }

        /// <summary>
        /// 根据id更新会议申请为已批准
        /// </summary>
        /// <param name="id"></param>
        public void UpdateApplyMeetingIsAgree(int id)
        {
            XPCollection xp = new XPCollection(typeof(ApplyMeeting), new BinaryOperator("Oid", id, BinaryOperatorType.Equal));
            foreach (ApplyMeeting am in xp)
            {
                am.Am_isagree = "已批准";   //or不批准
                am.Save();
            }
        }

        /// <summary>
        /// 保存公文审批信息，如果不批准流程，则修改公文申请表状态
        /// </summary>
        /// <param name="documentApprove"></param>
        public void SaveMeetingApprove(MeetingApprove meetingApprove)
        {
            if (meetingApprove.Ma_result == "不批准")
            {
                meetingApprove.Applymeeting.Am_state = "结束";
                meetingApprove.Applymeeting.Am_isagree = "不批准";
            }
            meetingApprove.Save();
        }

        /// <summary>
        /// 会议归档
        /// </summary>
        public void SaveMeetingData(MeetingData meetingData, List<string> name, Room room, Dictionary<string, int> equipmentData)
        {
            SaveMeetingUser(name, meetingData);
            SaveMeetingRoom(room, meetingData);
            SaveMeetingEquipment(equipmentData, meetingData);
        }

        /// <summary>
        /// 保存会议申请所参加的用户
        /// </summary>
        /// <param name="name"></param>
        /// <param name="meetingData"></param>
        public void SaveMeetingUser(List<string> name,MeetingData meetingData)
        {
            UserService us = new UserService();
            for (int i = 0; i < name.Count; i++)
            {
                MeetingUser meetingUser = new MeetingUser();
                meetingUser.UserData = us.GetUser(name[i]);
                meetingUser.Meetingdata = meetingData;
                meetingUser.Save();
            }
        }

        /// <summary>
        /// 保存会议申请使用的会议室
        /// </summary>
        /// <param name="room"></param>
        /// <param name="meetingData"></param>
        public void SaveMeetingRoom(Room room,MeetingData meetingData)
        {
            MeetingRoom meetingRoom = new MeetingRoom();
            meetingRoom.Room = room;
            meetingRoom.Meetingdata = meetingData;
            meetingRoom.Save();
        }

        ///// <summary>
        ///// 会议申请使用的设备
        ///// </summary>
        ///// <param name="equipment"></param>
        ///// <param name="count"></param>
        ///// <param name="meetingData"></param>
        ////public void SaveMeetingEquipment(List<Equipment> equipment, int equipmentCount, MeetingData meetingData)
        ////{
        ////    for (int i = 0; i < equipment.Count; i++)
        ////    {
        ////        MeetingEquipment meetingEquipment = new MeetingEquipment();
        ////        meetingEquipment.Equipment = equipment[i];
        ////        meetingEquipment.Me_count = equipmentCount;
        ////        meetingEquipment.Meetingdata = meetingData;
        ////        meetingEquipment.Save();
        ////    }
        ////}

        /// <summary>
        /// 会议申请使用的设备
        /// </summary>
        /// <param name="equipmentData"></param>
        /// <param name="meetingData"></param>
        public void SaveMeetingEquipment(Dictionary<string, int> equipmentData, MeetingData meetingData)
        {
            MeetingService ms = new MeetingService();
            foreach (KeyValuePair<string, int> pair in equipmentData)
            {
                MeetingEquipment meetingEquipment = new MeetingEquipment();
                meetingEquipment.Equipment = ms.GetEquipment(pair.Key);
                meetingEquipment.Me_count = pair.Value;
                meetingEquipment.Meetingdata = meetingData;
                meetingEquipment.Save();
            }
        }

        /// <summary>
        /// 更新会议室状态为使用中or空闲中
        /// </summary>
        /// <param name="id"></param>
        public void UpdateRoomState(int id,string state)
        {
            XPCollection xp = new XPCollection(typeof(Room), new BinaryOperator("room_state",id,BinaryOperatorType.Equal));
            foreach(Room r in xp)
            {
                r.Room_state = state;   //使用中or空闲中
                r.Save();
            }
        }

        /// <summary>
        /// 查找空闲会议室
        /// </summary>
        /// <returns></returns>
        public XPCollection SelectFreeRoom()
        {
            XPCollection xp = new XPCollection(typeof(Room),new BinaryOperator("room_state","空闲中",BinaryOperatorType.Equal));
            return xp;
        }

        /// <summary>
        /// 更新会议状态和会议室状态
        /// </summary>
        public void UpdateMeetingDataState()
        {
            XPCollection xp = new XPCollection(typeof(MeetingData),new BinaryOperator("Md_state","未开始",BinaryOperatorType.Equal));
            foreach(MeetingData md in xp)
            {
                if (DateTime.Compare(DateTime.Now, md.Md_endtime) > 0)
                {
                    md.Md_state = "已结束";
                    md.Meetingroom.Room.Room_state = "空闲中";
                    md.Save();
                }
            }
        }

        /// <summary>
        /// 判断会议室是否在特定时间内是否空闲
        /// </summary>
        /// <param name="roomId"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        public bool RoomIsFree(string roomName, DateTime startTime, DateTime endTime)
        {
            bool result = true;
            Room room = null;
            XPCollection xpRoom = new XPCollection(typeof(Room), new BinaryOperator("Room_name", roomName, BinaryOperatorType.Equal));
            foreach (Room r in xpRoom)
            {
                room = r;
            }
            //XPCollection xp = new XPCollection(typeof(MeetingRoom), new BinaryOperator("Room", room, BinaryOperatorType.Equal));
            XPCollection xp = room.meetingrooms;
            foreach (MeetingRoom mr in xp)
            {
                if (mr.Meetingdata.Md_state == "未开始")//已结束
                {   //如果开始时间和结束时间在会议申请信息表开始时间和结束时间中间
                    if ((DateTime.Compare(startTime, mr.Meetingdata.Md_starttime) >= 0 && DateTime.Compare(startTime, mr.Meetingdata.Md_endtime) <= 0) || (DateTime.Compare(endTime, mr.Meetingdata.Md_starttime) >= 0 && DateTime.Compare(endTime, mr.Meetingdata.Md_endtime) <= 0))
                    {
                        result = false;
                    }
                    //如果开始时间在会议申请信息表开始时间之前且结束时间在会议申请信息表结束时间之后
                    if (DateTime.Compare(startTime, mr.Meetingdata.Md_starttime) < 0 && DateTime.Compare(endTime, mr.Meetingdata.Md_endtime) > 0)
                    {
                        result = false;
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 查询设备是否足够使用
        /// </summary>
        /// <param name="name"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="equipment"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public bool EquipmentIsEnough(DateTime startTime, DateTime endTime, Equipment equipment, int count)
        {
            bool result = true;
            GroupOperator go1 = new GroupOperator();
            go1.Operands.Add(new BinaryOperator("Md_starttime", startTime, BinaryOperatorType.GreaterOrEqual));
            go1.Operands.Add(new BinaryOperator("Md_endtime", startTime, BinaryOperatorType.LessOrEqual));
            GroupOperator go2 = new GroupOperator();
            go2.Operands.Add(new BinaryOperator("Md_starttime", endTime, BinaryOperatorType.GreaterOrEqual));
            go2.Operands.Add(new BinaryOperator("Md_endtime", endTime, BinaryOperatorType.LessOrEqual));
            GroupOperator go3 = new GroupOperator(GroupOperatorType.Or, go1, go2);
            GroupOperator go4 = new GroupOperator();
            go4.Operands.Add(new BinaryOperator("Md_starttime", startTime, BinaryOperatorType.LessOrEqual));
            go4.Operands.Add(new BinaryOperator("Md_endtime", endTime, BinaryOperatorType.GreaterOrEqual));
            GroupOperator go = new GroupOperator(GroupOperatorType.Or, go3, go4);

            XPCollection xp = new XPCollection(typeof(MeetingData), go);
            int busyCount = 0;
            foreach (MeetingData md in xp)
            {
                foreach (MeetingEquipment me in md.meetingequipments)
                {
                    if (me.Equipment == equipment)
                    {
                        busyCount += me.Me_count;//计算在特定时间内使用的总设备数
                    }
                }
            }

            MeetingService ms = new MeetingService();
            int freeCount = ms.GetEquipment(equipment.Eq_name).Eq_count - busyCount;//得到空闲数量

            if (count > freeCount)//申请数量大于空闲数量
            {
                result = false;
            }
            return result;
        }

        /// <summary>
        /// 根据会议室名返回会议室对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public Room GetRoom(string name)
        {
            Room room = null;
            XPCollection xp = new XPCollection(typeof(Room), new BinaryOperator("Room_name", name, BinaryOperatorType.Equal));
            foreach (Room r in xp)
            {
                room = r;
            }
            return room;
        }

        /// <summary>
        /// 根据设备名返回设备对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public Equipment GetEquipment(string name)
        {
            Equipment equipment = null;
            XPCollection xp = new XPCollection(typeof(Equipment), new BinaryOperator("Eq_name", name, BinaryOperatorType.Equal));
            foreach (Equipment e in xp)
            {
                equipment = e;
            }
            return equipment;
        }
        
    }
}